import fs from "fs";
import path from "path";
import ejs from "ejs";
import parser from "@babel/parser";
import traverse from "@babel/traverse";
import babelCore from "babel-core";
let id = 0

function createAsset (filePath) {
    // 获取文件内容
    // 获取依赖关系
    // ast ==>抽象语法树
    const source = fs.readFileSync(filePath, {
        encoding: 'utf-8'
    })

    const ast = parser.parse(source, {
        sourceType: 'module'
    })

    const deps = []
    // 通过ast获取文件内依赖的文件
    // 参考：https://astexplorer.net/
    traverse.default(ast, {
        ImportDeclaration ({ node }) {
            deps.push(node.source.value)
        }
    })
    // 将import 转为  require形式
    const { code } = babelCore.transformFromAst(ast, null, {
        presets: ['env']
    })
    return {
        filePath,
        code,
        deps,
        mapping: {},
        id: id++
    }
}
// const asset = createAsset()
// console.log(332, asset)

function createGraph () {
    const mainAsset = createAsset('./example/main.js')

    const queue = [mainAsset]
    for (const asset of queue) {
        asset.deps.forEach(relativePath => {
            const child = createAsset(path.resolve('./example', relativePath))
            asset.mapping[relativePath] = child.id
            queue.push(child)
        });
    }

    // 最终文件引用依赖图
    return queue
}
const graph = createGraph();

// 构建函数
function build (graph) {
    const template = fs.readFileSync('./bundle.ejs', {
        encoding: 'utf-8'
    })
    const data = graph.map((asset) => {
        return {
            id: asset.id,
            mapping: asset.mapping,
            code: asset.code
        }
    })
    const code = ejs.render(template, { data })


    //创建文件
    fs.writeFileSync('./dist/bundle.js', code)
}
build(graph)